#include <QgsSimulation/MoveGeometryTools.h>

using SimulationCore::QgsSimulation::MoveGeometryTools;

MoveGeometryTools::MoveGeometryTools(QgsMapCanvas *mapcanvas,
	QgsCoordinateReferenceSystem &src_crs, QgsCoordinateReferenceSystem &dst_crs,
	QgsVectorLayer* layer, QgsFeatureId id)
	:QgsMapToolEmitPoint(mapcanvas),
	mapcanvas_(mapcanvas),
	src_crs_(src_crs), dst_crs_(dst_crs),
	m_layer_(layer)
{
	this->m_feature_ = this->m_layer_->getFeature(id);
	this->transform = QgsCoordinateTransform(src_crs, dst_crs, QgsProject::instance());
	this->m_is_move_ = false;
}

void MoveGeometryTools::canvasPressEvent(QgsMapMouseEvent * e)
{
	auto point = e->mapPoint();
	auto point_geom = QgsGeometry::fromPointXY(point);
	if (e->button() == Qt::LeftButton) {
		auto geometry = this->m_feature_.geometry();
		geometry.transform(this->transform, QgsCoordinateTransform::ReverseTransform);

		if (geometry.contains(point_geom)) {
			if (this->m_layer_->isEditable() || this->m_layer_->startEditing()) {
				this->m_is_move_ = true;
				this->m_point_origin_ = point;
				this->m_geometry_ = QgsGeometry::fromWkt(this->m_feature_.geometry().asWkt());
			}
		}
	}
	else if (e->button() == Qt::RightButton) {
		if (this->m_is_move_) {
			this->m_feature_.setGeometry(this->m_geometry_);
			
			if (this->m_layer_->isEditable()) {
				this->m_layer_->updateFeature(this->m_feature_);
				if (!this->m_layer_->commitChanges()) {
					this->m_layer_->rollBack();
				}
				this->m_layer_->triggerRepaint();
			}
			this->m_is_move_ = false;
		}
	}
}

void MoveGeometryTools::canvasMoveEvent(QgsMapMouseEvent * e)
{
	if (this->m_is_move_) {
		auto geometry = QgsGeometry::fromWkt(this->m_geometry_.asWkt());
		auto point = e->mapPoint();

		geometry.transform(this->transform, QgsCoordinateTransform::ReverseTransform);

		geometry.translate(
			point.x() - this->m_point_origin_.x(),
			point.y() - this->m_point_origin_.y());

		geometry.transform(this->transform);

		this->m_feature_.setGeometry(geometry);

		if (this->m_layer_->isEditable() ) {
			this->m_layer_->updateFeature(this->m_feature_);
			this->m_layer_->triggerRepaint();
		}
	}
}

void MoveGeometryTools::canvasReleaseEvent(QgsMapMouseEvent * e)
{
	if (e->button() == Qt::LeftButton) {
		if (this->m_is_move_) {
			auto geometry = QgsGeometry::fromWkt(this->m_geometry_.asWkt());
			auto point = e->mapPoint();

			geometry.transform(this->transform, QgsCoordinateTransform::ReverseTransform);

			geometry.translate(
				point.x() - this->m_point_origin_.x(),
				point.y() - this->m_point_origin_.y());

			geometry.transform(this->transform);

			this->m_feature_.setGeometry(geometry);
		}

		if (this->m_layer_->isEditable()) {
			this->m_layer_->updateFeature(this->m_feature_);
			if (!this->m_layer_->commitChanges()) {
				this->m_layer_->rollBack();
			}
			this->m_layer_->updateExtents();
			this->m_layer_->triggerRepaint();

			emit featureChanged(this->m_layer_, this->m_feature_);
		}
		this->m_is_move_ = false;
	}
}

void MoveGeometryTools::deactivate()
{
	QgsMapToolEmitPoint::deactivate();
}
